﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using Kevin.Comm.Logger;
using Kevin.Shop.Business.Service.Entity.Helper;
using Kevin.Shop.Business.Service.Entity.SalesManagement.Order;
using Kevin.Shop.Integration.PaymentInterface.AlipayMobile;
using RiderShop.Mobile.Common.Component;
using RiderShop.Mobile.Modle.Purchase;
using Kevin.Shop.Business.Core.Configuration;


namespace RiderShop.Mobile.Controllers.Purchase
{
    public partial class PurchaseController : ThemeController
    {
        private string partner = ConfigurationManager.AppSettings["AlipayPartner"];
        private string sellerEmail = ConfigurationManager.AppSettings["AlipaySeller_email"];
        private string signType = ConfigurationManager.AppSettings["Sign_Type"];
        [Authorize]
        public ActionResult Payment()
        {
            var orderNumber = Request.QueryString["orderNumber"];
            var paymentType = Request.QueryString["paymentType"];
            var model = new PaymentModel();
            var order = model.GetOrderBasicInfoByOrderId(orderNumber);
            //支付宝网关地址
            string GATEWAY_NEW = "http://wappaygw.alipay.com/service/rest.htm?";

            ////////////////////////////////////////////调用授权接口alipay.wap.trade.create.direct获取授权码token////////////////////////////////////////////
            //返回格式
            string format = "xml";
            //必填，不需要修改

            //返回格式
            string v = "2.0";
            //必填，不需要修改

            //请求号
            string req_id = WebClientContext.Current.UserId.ToString() + "-" + DateTime.Now.ToString("yyyyMMddHHmmss");
            //必填，须保证每次请求都是唯一

            //req_data详细信息

            //服务器异步通知页面路径
            string notify_url = ConfigurationManager.AppSettings["Notify_Url"];
            //需http://格式的完整路径，不允许加?id=123这类自定义参数

            //页面跳转同步通知页面路径
            string call_back_url = ConfigurationManager.AppSettings["Callback_Url"];
            //需http://格式的完整路径，不允许加?id=123这类自定义参数

            //卖家支付宝帐户
            string seller_email = sellerEmail;
            //必填

            //商户订单号
            string out_trade_no = orderNumber;
            //商户网站订单系统中唯一订单号，必填

            //订单名称
            string subject = "RiderShop-" + orderNumber;
            //必填

            //付款金额
            string total_fee = order.OrderPayAmount.ToString();
            //必填

            //请求业务参数详细
            string req_dataToken = "<direct_trade_create_req><notify_url>" + notify_url + "</notify_url><call_back_url>" + call_back_url + "</call_back_url><seller_account_name>" + seller_email + "</seller_account_name><out_trade_no>" + out_trade_no + "</out_trade_no><subject>" + subject + "</subject><total_fee>" + total_fee + "</total_fee></direct_trade_create_req>";
            //必填
            //把请求参数打包成数组
            Dictionary<string, string> sParaTempToken = new Dictionary<string, string>();
            sParaTempToken.Add("partner", partner);
            sParaTempToken.Add("_input_charset", Config.Input_charset.ToLower());
            sParaTempToken.Add("sec_id", signType);
            sParaTempToken.Add("service", "alipay.wap.trade.create.direct");
            sParaTempToken.Add("format", format);
            sParaTempToken.Add("v", v);
            sParaTempToken.Add("req_id", req_id);
            sParaTempToken.Add("req_data", req_dataToken);

            //建立请求
            string sHtmlTextToken = Submit.BuildRequest(GATEWAY_NEW, sParaTempToken);
            //URLDECODE返回的信息
            Encoding code = Encoding.GetEncoding(Config.Input_charset);
            sHtmlTextToken = HttpUtility.UrlDecode(sHtmlTextToken, code);

            //解析远程模拟提交后返回的信息
            Dictionary<string, string> dicHtmlTextToken = Submit.ParseResponse(sHtmlTextToken);

            //获取token
            string request_token = dicHtmlTextToken["request_token"];

            ////////////////////////////////////////////根据授权码token调用交易接口alipay.wap.auth.authAndExecute////////////////////////////////////////////


            //业务详细
            string req_data = "<auth_and_execute_req><request_token>" + request_token + "</request_token></auth_and_execute_req>";
            //必填

            //把请求参数打包成数组
            Dictionary<string, string> sParaTemp = new Dictionary<string, string>();
            sParaTemp.Add("partner", partner);
            sParaTemp.Add("_input_charset", Config.Input_charset.ToLower());
            sParaTemp.Add("sec_id", signType);
            sParaTemp.Add("service", "alipay.wap.auth.authAndExecute");
            sParaTemp.Add("format", format);
            sParaTemp.Add("v", v);
            sParaTemp.Add("req_data", req_data);

            //建立请求
            string sHtmlText = Submit.BuildRequest(GATEWAY_NEW, sParaTemp, "get", "确认");

            return Content(sHtmlText);
        }

        [ValidateInput(false)]
        public ActionResult PaymentNotify()
        {
            string result = "fail";
            try
            {
                Dictionary<string, string> sPara = GetRequestPost();
                Tracer.TraceLog("Payment Notify:" + sPara["traceInfo"], "orderPayment", "orderPayment", true);
                string trade_status = string.Empty;
                if (sPara.Count > 0)//判断是否有带返回参数
                {
                    Notify aliNotify = new Notify();
                    bool verifyResult = aliNotify.VerifyNotify(sPara, Request.Form["sign"]);
                    //if (verifyResult)//验证成功//签名验证总是错误
                    //{
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码
                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表

                    //解密（如果是RSA签名需要解密，如果是MD5签名则下面一行清注释掉）
                    //sPara = aliNotify.Decrypt(sPara);
                    //XML解析notify_data数据
                    XmlDocument xmlDoc = new XmlDocument();
                    xmlDoc.LoadXml(sPara["notify_data"]);
                    //商户订单号
                    string order_no = xmlDoc.SelectSingleNode("/notify/out_trade_no").InnerText;
                    //支付宝交易号
                    string trade_no = xmlDoc.SelectSingleNode("/notify/trade_no").InnerText;
                    //交易状态
                    trade_status = xmlDoc.SelectSingleNode("/notify/trade_status").InnerText;
                    //交易金额
                    string total_fee = xmlDoc.SelectSingleNode("/notify/price").InnerText;
                    //交易金额
                    string buyer_email = xmlDoc.SelectSingleNode("/notify/buyer_email").InnerText;
                    decimal order_fee = 0;
                    Decimal.TryParse(total_fee, out order_fee);
                    if (trade_status == "TRADE_FINISHED" || trade_status == "TRADE_SUCCESS")
                    {
                        PaymentModel model = new PaymentModel();
                        var order = model.GetOrderBasicInfoByOrderId(order_no);
                        var info = new OrderPaymentInfo
                                       {
                                           OrderNumber = order_no,
                                           TradeNumber = trade_no,
                                           TransferAmount = order.OrderPayAmount,
                                           InDate = DateTime.Now,
                                           BuyerPaymentID = buyer_email,
                                           PaymentPlatformType = 1,
                                           InUser = 100
                                       };
                        var response = RestfulHelper.Update(SiteUrl.FormatUrl("SalesManagement_CreateOrderPaymentInfo"), info);
                        result = "success";  //请不要修改或删除
                    }
                    //if (trade_status == "TRADE_FINISHED")
                    //{
                    //    //判断该笔订单是否在商户网站中已经做过处理
                    //    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //    //如果有做过处理，不执行商户的业务程序

                        //    //注意：
                    //    //该种交易状态只在两种情况下出现
                    //    //1、开通了普通即时到账，买家付款成功后。
                    //    //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。

                        //    //Response.Write("success");  //请不要修改或删除
                    //}
                    //else if (trade_status == "TRADE_SUCCESS")
                    //{
                    //    //判断该笔订单是否在商户网站中已经做过处理
                    //    //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                    //    //如果有做过处理，不执行商户的业务程序
                    //    //注意：
                    //    //该种交易状态只在一种情况下出现——开通了高级即时到账，买家付款成功后。

                        //    //Response.Write("success");  //请不要修改或删除
                    //    //修改订单状态&新建支付信息

                        //}
                    else
                    {
                        result = trade_status;
                    }
                }
                else//验证失败
                {
                    result = "fail";
                    Tracer.TraceLog("签名验证失败", string.Empty, "orderPayment", false);
                }
                //}
                Tracer.TraceLog("Payment Notify Payment:" + trade_status, string.Empty, "orderPayment", false);
            }
            catch (Exception e)
            {
                Tracer.TraceLog("Payment Notify Payment Error:" + e, string.Empty, "orderPayment", false);
            }

            return Content(result);
        }

        /// <summary>
        /// 根据用户的openid算出加密签名
        /// </summary>
        /// <param name="openId">openId</param>
        /// <returns></returns>
        public string GetSha1(string openId)
        {
            //建立SHA1对象
            System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();
            //将mystr转换成byte[] 
            ASCIIEncoding enc = new ASCIIEncoding();
            byte[] dataToHash = enc.GetBytes(openId);
            //Hash运算
            byte[] dataHashed = sha.ComputeHash(dataToHash);
            //将运算结果转换成string
            string hash = BitConverter.ToString(dataHashed).Replace("-", "");
            return hash;
        }

        /// <summary>
        /// 订单支付完成界面
        /// </summary>
        /// <param name="orderNumber">订单号</param>
        /// <returns></returns>
        public ActionResult PaymentCompleted(string orderNumber = "")
        {
            if (string.IsNullOrEmpty(orderNumber))
            {
                return View(WebClientContext.Current.SiteTheme, "Purchase", "PaymentCompleted", WebClientContext.Current.CacheKeyDefaultMasterPage, null);
            }
            PaymentModel model = new PaymentModel();
            var order = model.GetOrderBasicInfoByOrderId(orderNumber);
            if (order == null)
            {
                return View(WebClientContext.Current.SiteTheme, "Purchase", "PaymentCompleted", WebClientContext.Current.CacheKeyDefaultMasterPage, null);
            }
            //如果订单中的商品是'情人节活动商品'跳转到排名界面
            if (order.ProductList.Any(p => "10430002005".Contains(p.ProductId)))
            {
                bool activitySwitch = false;
                bool.TryParse(ConfigurationManager.AppSettings["ActivitySwitch"], out activitySwitch);
                if (activitySwitch)
                {
                    if (!string.IsNullOrEmpty(order.UserMemo))
                    {
                        order.UserMemo = order.UserMemo.Trim().Replace("ActivityPrd-", "");//用户挑选的商品
                    }
                    else
                    {
                        order.UserMemo = "0";
                    }
                    //组织要传回去的参数portal name & signature
                    string portalName = ConfigurationManager.AppSettings["WeixinPortalName"];
                    string activityId = ConfigurationManager.AppSettings["ActivityId"];
                    string openId = WebClientContext.Current.CurrentUser.ThirdUserId.ToLower().Replace("weixing_", "").Replace("weixin_", "");
                    string signature = GetSha1(openId).ToString().ToLower();

                    //return Redirect("http://localhost:6452/Activity/QingRenJieRank?payComplete=finished&id=" + activityId + "&portal=" + portalName + "&pid=" + order.UserMemo + "&signature=" + signature);                               
                    return Redirect("http://m.rongji365.com/weixinportal/Activity/QingRenJieRank?payComplete=finished&id="
                        + activityId + "&portal=" + portalName + "&pid=" + order.UserMemo + "&signature=" + signature + "&address=" + order.ReceiveAddress);
                }
            }
            //如果是送礼订单支付成功的话需要跳到送礼订单的界面
            if (order.OrderType != 6)
            {
                return View(WebClientContext.Current.SiteTheme, "Purchase", "PaymentCompleted", WebClientContext.Current.CacheKeyDefaultMasterPage, null);
            }
            else
            {
                return RedirectToAction("GreetingOrderPaymentCompleted", "Purchase",new {orderNumber=orderNumber});
            }
        }


        [Authorize]
        [HttpGet]
        public ActionResult GreetingOrderPaymentCompleted(string orderNumber)
        {
            if (string.IsNullOrEmpty(orderNumber))
            {
                return new EmptyResult();
            }
            return View("~/Themes/" + WebClientContext.Current.SiteTheme + "/Views/Purchase/GreetingOrderPaymentCompleted.cshtml");
        }


        [ValidateInput(false)]
        public ActionResult PaymentCallback()
        {
            Dictionary<string, string> sPara = GetRequestGet();
            Kevin.Comm.Logger.Tracer.TraceLog("Payment callback:" + sPara["traceInfo"], "orderPayment", "orderPayment", true);
            //商户订单号
            string order_no = Request.QueryString["out_trade_no"];

            //支付宝交易号
            string trade_no = Request.QueryString["trade_no"];

            //交易状态
            string result = Request.QueryString["result"];

            if (result.ToLower() == "success")
            {
                //修改订单状态&新建支付信息
                PaymentModel model = new PaymentModel();
                var order = model.GetOrderBasicInfoByOrderId(order_no);
                var info = new OrderPaymentInfo
                {
                    OrderNumber = order_no,
                    TradeNumber = trade_no,
                    TransferAmount = order.OrderPayAmount,
                    InDate = DateTime.Now,
                    BuyerPaymentID = sellerEmail,
                    PaymentPlatformType = 1,
                    InUser = 100   //InUser还得考虑一下如何搞啊
                };
                var response = RestfulHelper.Update(SiteUrl.FormatUrl("SalesManagement_CreateOrderPaymentInfo"), info);

                //For testing add comment
                //if (order.ProductList.Any(p => "10050001001  10040002001  10390002005  10390002006 10390002007  10390002008  10390002009  10390002010".Contains(p.ProductId)))
                //{
                //    return RedirectToAction("PublishComment", "MyAccount", new { prd = order.ProductList[0].ProductId, orderNumber = order.OrderNumber, ft = 1 });
                //}


                return RedirectToAction("PaymentCompleted", new { orderNumber = order.OrderNumber });
            }
            return new EmptyResult();
        }

        /// <summary>
        /// 获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public Dictionary<string, string> GetRequestGet()
        {

            int i = 0;
            Dictionary<string, string> sArray = new Dictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;
            var logInfo = new StringBuilder();
            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.QueryString[requestItem[i]]);
                logInfo.AppendLine("key:" + requestItem[i] + " vlaue:" + Request.QueryString[requestItem[i]]);
            }
            sArray.Add("traceInfo", logInfo.ToString());
            return sArray;
        }

        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public Dictionary<string, string> GetRequestPost()
        {
            int i = 0;
            Dictionary<string, string> sArray = new Dictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.Form;
            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;
            var logInfo = new StringBuilder();
            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
                logInfo.AppendLine("key:" + requestItem[i] + " vlaue:" + Request.Form[requestItem[i]]);
            }
            sArray.Add("traceInfo", logInfo.ToString());
            return sArray;
        }
    }
}
